package com.coalmine.api.controller;

import com.alibaba.druid.pool.DruidPooledConnection;
import com.alibaba.fastjson.JSONObject;
import com.coalmine.api.domain.ApiDatasource;
import com.coalmine.api.service.IApiConfigService;
import com.coalmine.api.service.IApiDatasourceService;
import com.coalmine.api.util.JdbcUtil;
import com.coalmine.api.util.PoolManager;
import com.coalmine.api.util.RedisPoolManager;
import com.coalmine.common.core.domain.AjaxResult;
import com.coalmine.common.exception.ServiceException;
import com.coalmine.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import redis.clients.jedis.Jedis;

import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 获取数据源所有表、表字段、字段备注
 * @author: zjx
 * @create: 2021-04-12 15:07
 **/
@Slf4j
@Api(value="数据源表管理API",tags={"API数据源表管理接口"})
@RestController
@RequestMapping("/api/table")
public class ApiTableController {

    @Autowired
    IApiDatasourceService apiDatasourceService;

    @Autowired
    IApiConfigService apiConfigService;

    /**
     * 查询所有表
     * @return AjaxResult
     */
    //@PreAuthorize("@ss.hasPermi('table:list')")
    @ApiOperation("查询所有表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sourceId", required = true, value = "数据源id", dataType = "String", dataTypeClass = String.class)
    })
    @GetMapping("/getAllTables/{sourceId}")
    public AjaxResult getAllTables(@PathVariable String sourceId) {
        ApiDatasource apiDatasource = apiDatasourceService.detail(sourceId);
        //如果是redis数据源，不用druid
        if(StringUtils.equals("redis",apiDatasource.getType())){
            Jedis jedis = RedisPoolManager.getRedisPooledConnection(apiDatasource);
            Set<String> set = jedis.keys("*");
            List<JSONObject> list = new ArrayList<>();
            for (String s:set){
                JSONObject jo = new JSONObject();
                jo.put("label", s);
                jo.put("comment", "");
                jo.put("showColumns", false);
                list.add(jo);
            }
            return AjaxResult.success(list);
        }
        //非redis，继续执行
        DruidPooledConnection connection = null;
        try {
            connection = PoolManager.getPooledConnection(apiDatasource);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            throw new ServiceException("数据源连接异常！");
        }
        //List<String> tables = JdbcUtil.getAllTables(connection, apiDatasource.getTableSql());
        Map<String, String> allTables = JdbcUtil.getAllTables(connection, apiDatasource.getTableSql());
        Set<String> tables = allTables.keySet();
        TreeSet<String> set = new TreeSet<>();
        set.addAll(tables);
        List<JSONObject> list = null;
        if (tables != null) {
            list = set.stream().map(t -> {
                JSONObject jo = new JSONObject();
                jo.put("label", t);
                jo.put("comment", allTables.get(t));
                try {
                    DruidPooledConnection conn = PoolManager.getPooledConnection(apiDatasource);
                    jo.put("columns", JdbcUtil.getRDBMSColumnsPropertie(conn, apiDatasource.getType(), t));
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new ServiceException("数据源连接异常！");
                }
                jo.put("showColumns", false);
                return jo;
            }).collect(Collectors.toList());
        }
        return AjaxResult.success(list);
    }



    /**
     * 查询所有列
     * @return AjaxResult
     */
    //@PreAuthorize("@ss.hasPermi('table:columns')")
    @ApiOperation("查询所有列")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sourceId", required = true,value = "数据源id", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "table", required = true ,value = "表名", dataType = "String", dataTypeClass = String.class),
    })
    @PostMapping("/getAllColumns")
    public AjaxResult getAllTables(String sourceId, String table) throws SQLException {
        ApiDatasource apiDatasource = apiDatasourceService.detail(sourceId);
        List<JSONObject> columns = null;
        if(!StringUtils.equals("redis",apiDatasource.getType())){
            DruidPooledConnection connection = PoolManager.getPooledConnection(apiDatasource);
            columns = JdbcUtil.getRDBMSColumnsPropertie(connection, apiDatasource.getType(), table);
        }
        return AjaxResult.success(columns);
    }

    /**
     * 获取自定义sql的结果集备注
     * @return AjaxResult
     */
    //@PreAuthorize("@ss.hasPermi('table:columns')")
    @ApiOperation("获取自定义sql的结果集备注")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sourceId", value = "数据源id",required = true, dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "sql", value = "自定义sql",required = true,  dataType = "String", dataTypeClass = String.class),
    })
    @PostMapping("/getSqlResult")
    public AjaxResult getSqlResult(String sourceId, String sql) throws SQLException {
        ApiDatasource apiDatasource = apiDatasourceService.detail(sourceId);
        List<Map<String,String>> columns = null;
        if(!StringUtils.equals("redis",apiDatasource.getType())) {
            columns = JdbcUtil.getSqlResult(apiDatasource, sql,null);
        }
        return AjaxResult.success(columns);
    }

    /**
     * 获取自定义sql的结果
     * 非redis数据源的sql
     * @return AjaxResult
     */
    //@PreAuthorize("@ss.hasPermi('table:columns')")
    @ApiOperation("获取自定义sql的结果集")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sourceId", value = "数据源id",required = true, dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "sql", value = "自定义sql",required = true,  dataType = "String", dataTypeClass = String.class),
    })
    @PostMapping("/getSqlResultList")
    public AjaxResult getSqlResultList(String sourceId, String sql,String tableName) throws SQLException {
        ApiDatasource apiDatasource = apiDatasourceService.detail(sourceId);
        // 为空时自动获取自定义的sql
        if (StringUtils.isEmpty(sql)){
            ApiDatasource detail = apiDatasourceService.detail(sourceId);
            sql = detail.getTableSql();
        }

        Object o = JdbcUtil.getSqlResultList(apiDatasource, sql,null);
        // 模糊搜索
        if (StringUtils.isNotEmpty(tableName)){
            List<JSONObject> jsonObjectLis  = (List<JSONObject>) o;
            List<JSONObject> newList = new ArrayList<>();
            jsonObjectLis.stream().forEach(json ->{
                String table = json.getString("tableName");
                if (table.contains(tableName)){
                    newList.add(json);
                }
            });
            return AjaxResult.success(newList);
        }
        return AjaxResult.success(o);
    }

}
